import Vue from 'vue';
import Store from '@/store'
import md5 from 'js-md5'

const util = {
    /*
    --------------------------------------------通用数据处理--------------------------------------------
    */
    //数组处理，合并去重
    arrCombine() {
        let arr = [].concat.apply([], arguments);  //合并操作：concat()返回的是连接后的新数组，此时并没有去重
        return Array.from(new Set(arr));  //去重操作：new Set(),返回值是一个去重后新的Set对象,用Array.from()将对象转化为数组
    },
    //数组处理，删除指定元素
    arrSplice(arrylist, val) {
        for (var i = 0; i < arrylist.length; i++) {
            if (arrylist[i] == val) {
                arrylist.splice(i, 1);
                break;
            }
        }
        return arrylist;
    },
    //数据字典，获取数据字典列表数据
    getDataItemList(itemCode) {
        return Store.state.user.dataitemlist.filter(dataItem => dataItem.B_ItemCode === itemCode);
    },
    //树型处理，删除空的children，删除指定节点
    removeChildren(treeList, disabledId) {
        for (var i = treeList.length - 1; i >= 0; i--) {
            //删除指定节点
            if (treeList[i].id === disabledId) {
                treeList.splice(i, 1);
                continue;
            }

            //删除空的children
            if (treeList[i].children.length == 0) {
                delete treeList[i].children;
            } else {
                this.removeChildren(treeList[i].children, disabledId);
            }
        }
        return treeList || [];
    },
    //树型处理，获取树型深度数组（默认以id回显）
    getTreeDeepArr(id, treeList, id_value) {
        if (!id_value) id_value = 'id'; ////默认以id回显
        let arr = []; // 在递归时操作的数组
        let returnArr = []; // 存放结果的数组
        let depth = 0; // 定义全局层级
        // 定义递归函数
        function childrenEach(childrenData, depthN) {

            for (var j = 0; j < childrenData.length; j++) {

                depth = depthN; // 将执行的层级赋值 到 全局层级

                arr[depthN] = (childrenData[j][id_value]);

                if (childrenData[j][id_value] == id) {

                    returnArr = arr.slice(0, depthN + 1); //将目前匹配的数组，截断并保存到结果数组，
                    break

                } else {

                    if (childrenData[j].children) {

                        depth++;
                        childrenEach(childrenData[j].children, depth);

                    }
                }

            }
            return returnArr;
        }
        return childrenEach(treeList, depth);
    },
    //树型处理，获取树型本身节点及其所有子节点
    getTreeSubNodes(treeList, parentId) {
        let res = []; // 在递归时操作的数组
        // 定义递归函数
        function childrenEach(childrenData, id) {
            for (var i = 0; i < childrenData.length; i++) {
                if (childrenData[i].id == parentId) {
                    res.push(childrenData[i]);
                    break;
                }
                if (childrenData[i].hasChildren) {
                    childrenEach(childrenData[i].children, parentId);
                }
            }
            return res;
        }
        return childrenEach(treeList, parentId);
    },
    //树型处理，获取全选与半选的Id
    getTreeCheckedIds(tree) {
        var parentArr = tree.getHalfCheckedKeys();
        var childArr = tree.getCheckedKeys();
        return this.arrCombine(parentArr, childArr);
    },
    //树型处理，去除父级半选状态Id
    removeHalfCheck(checkedIds, treeList) {
        var newArr = [];
        //定义函数
        function checked(id, data, newArr) {
            data.forEach(item => {
                if (item.id == id) {
                    if (item.children === undefined) {
                        newArr.push(item.id)
                    }
                } else {
                    if (item.children !== undefined) {
                        checked(id, item.children, newArr)
                    }
                }
            });
        };
        checkedIds.forEach(item => {
            checked(item, treeList, newArr)
        })
        return newArr;
    },
    /*
    --------------------------------------------通用数据验证--------------------------------------------
    */
    validateURL(textval) {
        const urlregex = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/
        return urlregex.test(textval)
    },
    validatePhone(s) {
        return /^([0-9]{3,4}-)?[0-9]{7,8}$/.test(s)
    },
    isURL(s) {
        return /^http[s]?:\/\/.*/.test(s)
    },
    validateLowerCase(str) {
        const reg = /^[a-z]+$/
        return reg.test(str)
    },
    validateUpperCase(str) {
        const reg = /^[A-Z]+$/
        return reg.test(str)
    },
    validateAlphabets(str) {
        const reg = /^[A-Za-z]+$/
        return reg.test(str)
    },
    vaildatePc() {
        const userAgentInfo = navigator.userAgent;
        const Agents = ["Android", "iPhone",
            "SymbianOS", "Windows Phone",
            "iPad", "iPod"
        ];
        let flag = true;
        for (var v = 0; v < Agents.length; v++) {
            if (userAgentInfo.indexOf(Agents[v]) > 0) {
                flag = false;
                break;
            }
        }
        return flag;
    },
    validateEmail(email) {
        const re = /^(([^<>()\\[\]\\.,;:\s@"]+(\.[^<>()\\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
        return re.test(email)
    },
    validateCardId(code) {
        let list = [];
        let result = true;
        let msg = '';
        var city = {
            11: "北京",
            12: "天津",
            13: "河北",
            14: "山西",
            15: "内蒙古",
            21: "辽宁",
            22: "吉林",
            23: "黑龙江 ",
            31: "上海",
            32: "江苏",
            33: "浙江",
            34: "安徽",
            35: "福建",
            36: "江西",
            37: "山东",
            41: "河南",
            42: "湖北 ",
            43: "湖南",
            44: "广东",
            45: "广西",
            46: "海南",
            50: "重庆",
            51: "四川",
            52: "贵州",
            53: "云南",
            54: "西藏 ",
            61: "陕西",
            62: "甘肃",
            63: "青海",
            64: "宁夏",
            65: "新疆",
            71: "台湾",
            81: "香港",
            82: "澳门",
            91: "国外 "
        };
        if (!this.validateNull(code)) {
            if (code.length == 18) {
                if (!code || !/(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(code)) {
                    msg = "证件号码格式错误";
                } else if (!city[code.substr(0, 2)]) {
                    msg = "地址编码错误";
                } else {
                    //18位身份证需要验证最后一位校验位
                    code = code.split('');
                    //∑(ai×Wi)(mod 11)
                    //加权因子
                    var factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
                    //校验位
                    var parity = [1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2, 'x'];
                    var sum = 0;
                    var ai = 0;
                    var wi = 0;
                    for (var i = 0; i < 17; i++) {
                        ai = code[i];
                        wi = factor[i];
                        sum += ai * wi;
                    }
                    if (parity[sum % 11] != code[17]) {
                        msg = "证件号码校验位错误";
                    } else {
                        result = false;
                    }

                }
            } else {
                msg = "证件号码长度不为18位";
            }

        } else {
            msg = "证件号码不能为空";
        }
        list.push(result);
        list.push(msg);
        return list;
    },
    validateMobile(phone) {
        let list = [];
        let result = true;
        let msg = '';
        var isPhone = /^0\d{2,3}-?\d{7,8}$/;
        //增加134 减少|1349[0-9]{7}，增加181,增加145，增加17[678]  
        if (!this.validateNull(phone)) {
            if (phone.length == 11) {
                if (isPhone.test(phone)) {
                    msg = '手机号码格式不正确';
                } else {
                    result = false;
                }
            } else {
                msg = '手机号码长度不为11位';
            }
        } else {
            msg = '手机号码不能为空';
        }
        list.push(result);
        list.push(msg);
        return list;
    },
    validateName(name) {
        var regName = /^[\u4e00-\u9fa5]{2,4}$/;
        if (!regName.test(name)) return false;
        return true;
    },
    validateNum(num, type) {
        let regName = /[^\d.]/g;
        if (type == 1) {
            if (!regName.test(num)) return false;
        } else if (type == 2) {
            regName = /[^\d]/g;
            if (!regName.test(num)) return false;
        }
        return true;
    },
    validateNumord(num, type) {
        let regName = /[^\d.]/g;
        if (type == 1) {
            if (!regName.test(num)) return false;
        } else if (type == 2) {
            regName = /[^\d.]/g;
            if (!regName.test(num)) return false;
        }
        return true;
    },
    validateNull(val) {
        if (typeof val == 'boolean') {
            return false;
        }
        if (typeof val == 'number') {
            return false;
        }
        if (val instanceof Array) {
            if (val.length == 0) return true;
        } else if (val instanceof Object) {
            if (JSON.stringify(val) === '{}') return true;
        } else {
            if (val == 'null' || val == null || val == 'undefined' || val == undefined || val == '') return true;
            return false;
        }
        return false;
    },
    isSameAsset(o1, o2) {
        return o1.B_AssetsId === o2.B_AssetsId && o1.B_PurchaseDate === o2.B_PurchaseDate;
    },
    isSameBarcode(o1, o2) {
        return o1.B_AssetsId === o2.B_AssetsId && o1.B_PurchaseDate === o2.B_PurchaseDate && o1.B_Barcode === o2.B_Barcode;
    },
    /*
    --------------------------------------------通用缓存操作--------------------------------------------
    */
    setStore(params = {}) {
        let {
            name,
            content,
            type,
        } = params;
        name = storeKeyName + name
        let obj = {
            dataType: typeof (content),
            content: content,
            type: type,
            datetime: new Date().getTime()
        }
        if (type) window.sessionStorage.setItem(name, JSON.stringify(obj));
        else window.localStorage.setItem(name, JSON.stringify(obj));
    },
    getStore(params = {}) {
        let {
            name,
            debug
        } = params;
        name = storeKeyName + name
        let obj = {},
            content;
        obj = window.sessionStorage.getItem(name);
        if (this.validateNull(obj)) obj = window.localStorage.getItem(name);
        if (this.validateNull(obj)) return;
        try {
            obj = JSON.parse(obj);
        } catch {
            return obj;
        }
        if (debug) {
            return obj;
        }
        if (obj.dataType == 'string') {
            content = obj.content;
        } else if (obj.dataType == 'number') {
            content = Number(obj.content);
        } else if (obj.dataType == 'boolean') {
            content = eval(obj.content);
        } else if (obj.dataType == 'object') {
            content = obj.content;
        }
        return content;
    },
    removeStore(params = {}) {
        let {
            name,
            type
        } = params;
        name = storeKeyName + name
        if (type) {
            window.sessionStorage.removeItem(name);
        } else {
            window.localStorage.removeItem(name);
        }

    },
    getAllStore(params = {}) {
        let list = [];
        let {
            type
        } = params;
        if (type) {
            for (let i = 0; i <= window.sessionStorage.length; i++) {
                list.push({
                    name: window.sessionStorage.key(i),
                    content: this.getStore({
                        name: window.sessionStorage.key(i),
                        type: 'session'
                    })
                })
            }
        } else {
            for (let i = 0; i <= window.localStorage.length; i++) {
                list.push({
                    name: window.localStorage.key(i),
                    content: this.getStore({
                        name: window.localStorage.key(i),
                    })
                })

            }
        }
        return list;

    },
    clearStore(params = {}) {
        let { type } = params;
        if (type) {
            window.sessionStorage.clear();
        } else {
            window.localStorage.clear()
        }

    },
    /*
    --------------------------------------------通用下载操作--------------------------------------------
    */
    //下载文件流
    downloadFile(apiUrl, params) {
        return new Promise((resolve, reject) => {
            if (apiUrl) {
                let note = Vue.prototype.$notify({
                    type: "success",
                    message: '正在下载，请稍后......',
                    showClose: false
                });
                let xhr = new XMLHttpRequest();
                let formData = new FormData();
                xhr.open('get', `${Store.state.app.root}${apiUrl}?${encodeParams(params)}`);  //url填写后台的接口地址，如果是post，在formData append参数（参考原文地址）
                xhr.setRequestHeader("Authorization", "Bearer " + Store.state.user.token);//header
                xhr.responseType = 'blob';
                xhr.onload = function (e) {
                    note.close();//关闭note提示
                    if (this.status == 200) {
                        let blob = this.response;
                        let filefullName = decodeURI(xhr.getResponseHeader("filename"));//解码防止中文乱码
                        if (window.navigator.msSaveOrOpenBlob) {
                            navigator.msSaveBlob(blob, filefullName);
                        } else {
                            let a = document.createElement('a');
                            let url = createObjectURL(blob);
                            a.href = url;
                            a.download = filefullName;
                            document.body.appendChild(a);
                            a.click();
                            window.URL.revokeObjectURL(url);
                        }
                        Vue.prototype.$notify({
                            type: "success",
                            message: '下载成功！',
                            showClose: false
                        });
                        resolve(this.response);
                    } else {
                        Vue.prototype.$notify({
                            type: "success",
                            message: '下载失败！',
                            showClose: false
                        });
                        reject(this.response);
                    }
                };
                xhr.send(formData);
            } else {
                reject('请求路径缺失！');
            }
        })
    },
    //下载文件流（form表单提交）
    downloadFileEx(apiUrl, params) {
        //js字符串转dom
        function parseDom(arg) {
            let objE = document.createElement("div");
            objE.innerHTML = arg;
            return objE.childNodes[0];
        };
        if (apiUrl && params) {
            var form = parseDom('<form action="' + apiUrl + '" method="post"></form>');//创建一个form元素
            //为form元素添加input标签，作为参数传递
            for (var key in params) {
                let input = parseDom('<input type="hidden" data-back="backdw" />');
                input.setAttribute('name', key);
                input.setAttribute('value', params[key]);
                form.append(input);
            }
            document.body.append(form);//将表单添加到body（否则表单无法提交）
            form.submit();//触发表单提交
            document.body.removeChild(form);//删除表单元素
        };
    },
    /*
    --------------------------------------------通用表单操作--------------------------------------------
    */
    //清除表单验证
    formClearValid() {
        function clearValidate(className){
            let elements = document.getElementsByClassName(className)
            for (let element of elements) {
                let vueCom = element.__vue__;
                if (vueCom != undefined && typeof vueCom.clearValidate === "function")
                    vueCom.clearValidate(); //清除表单验证
            }
        }
        clearValidate('el-form');
        clearValidate('vxe-form');
        clearValidate('vxe-grid');
    },
    //表单验证
    formValidate(arg) {
        //每次提交前重置验证返回结果的数组
        let promiseArr = [];
        function validate(className){
            let elements = document.getElementsByClassName(className)
            for (let element of elements) {
                let vueCom = element.__vue__;
                let result = new Promise((resolve, reject) => {
                    vueCom.validate().then(() => { resolve() }).catch(err => reject("表单验证不通过，请仔细检查！"))
                });
                promiseArr.push(result);
            }
        }
        validate('el-form');
        validate('vxe-form');
        validate('vxe-grid');
        Promise.all(promiseArr).then(() => {
            if (arg) arg()
        }).catch((data) => {
            Vue.prototype.$message({
                message: data,
                type: 'warning'
            });
        });
    },
    /*
    --------------------------------------------其他通用操作--------------------------------------------
    */
    newGUID() {
        let date = new Date();
        let guidStr = '';
        for (var i = 0; i < 9; i++) {
            guidStr += Math.floor(Math.random() * 16).toString(16);
        }
        guidStr += hexadecimal(getGUIDDate(date), 16);
        guidStr += hexadecimal(getGUIDTime(date), 16);
        while (guidStr.length < 32) {
            guidStr += Math.floor(Math.random() * 16).toString(16);
        }
        return formatGUID(guidStr);
    },
    md5
}

export default util;

/*
 * 缓存Key前缀
*/
const storeKeyName = 'rayd-';

/*
 * 获取blob对象URL地址
*/
const createObjectURL = (object) => { return (window.URL) ? window.URL.createObjectURL(object) : window.webkitURL.createObjectURL(object); }
/*
 * 拼接对象为请求字符串
 * param {Object} obj - 待拼接的对象
 * returns {string} - 拼接成的请求字符串
 */
const encodeParams = (obj) => {
    const params = []
    Object.keys(obj).forEach((key) => {
        let value = obj[key]
        // 如果值为undefined我们将其置空
        if (typeof value === 'undefined') {
            value = ''
        }
        // 对于需要编码的文本（比如说中文）我们要进行编码
        params.push([key, encodeURIComponent(value)].join('='))
    })
    return params.join('&')
}

/*
 * 功能：获取当前日期的GUID格式，即8位数的日期：19700101
 * 返回值：返回GUID日期格式的字条串
 */
const getGUIDDate = function (date) {
    return date.getFullYear() + addZero(date.getMonth() + 1) + addZero(date.getDay());
}
/*
* 功能：获取当前时间的GUID格式，即8位数的时间，包括毫秒，毫秒为2位数：12300933
* 返回值：返回GUID日期格式的字条串
*/
const getGUIDTime = function (date) {
    return addZero(date.getHours()) + addZero(date.getMinutes()) + addZero(date.getSeconds()) + addZero(parseInt(date.getMilliseconds() / 10));
}
/*
* 功能: 为一位数的正整数前面添加0，如果是可以转成非NaN数字的字符串也可以实现
 * 参数: 参数表示准备再前面添加0的数字或可以转换成数字的字符串
 * 返回值: 如果符合条件，返回添加0后的字条串类型，否则返回自身的字符串
 */
const addZero = function (num) {
    if (Number(num).toString() != 'NaN' && num >= 0 && num < 10) {
        return '0' + Math.floor(num);
    } else {
        return num.toString();
    }
}
/* 
 * 功能：将y进制的数值，转换为x进制的数值
 * 参数：第1个参数表示欲转换的数值；第2个参数表示欲转换的进制；第3个参数可选，表示当前的进制数，如不写则为10
 * 返回值：返回转换后的字符串
 */
const hexadecimal = function (num, x, y) {
    if (y != undefined) {
        return parseInt(num.toString(), y).toString(x);
    } else {
        return parseInt(num.toString()).toString(x);
    }
}
/*
 * 功能：格式化32位的字符串为GUID模式的字符串
 * 参数：第1个参数表示32位的字符串
 * 返回值：标准GUID格式的字符串
 */
const formatGUID = function (guidStr) {
    var str1 = guidStr.slice(0, 8) + '-',
        str2 = guidStr.slice(8, 12) + '-',
        str3 = guidStr.slice(12, 16) + '-',
        str4 = guidStr.slice(16, 20) + '-',
        str5 = guidStr.slice(20);
    return str1 + str2 + str3 + str4 + str5;
}